/* Copyright Statement:
 *
 * This software/firmware and related documentation ("AutoChips Software") are
 * protected under relevant copyright laws. The information contained herein is
 * confidential and proprietary to AutoChips Inc. and/or its licensors. Without
 * the prior written permission of AutoChips inc. and/or its licensors, any
 * reproduction, modification, use or disclosure of AutoChips Software, and
 * information contained herein, in whole or in part, shall be strictly
 * prohibited.
 *
 * AutoChips Inc. (C) 2023. All rights reserved.
 *
 * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
 * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("AUTOCHIPS SOFTWARE")
 * RECEIVED FROM AUTOCHIPS AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
 * ON AN "AS-IS" BASIS ONLY. AUTOCHIPS EXPRESSLY DISCLAIMS ANY AND ALL
 * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
 * NONINFRINGEMENT. NEITHER DOES AUTOCHIPS PROVIDE ANY WARRANTY WHATSOEVER WITH
 * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
 * INCORPORATED IN, OR SUPPLIED WITH THE AUTOCHIPS SOFTWARE, AND RECEIVER AGREES
 * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
 * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
 * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN AUTOCHIPS
 * SOFTWARE. AUTOCHIPS SHALL ALSO NOT BE RESPONSIBLE FOR ANY AUTOCHIPS SOFTWARE
 * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
 * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND AUTOCHIPS'S
 * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE AUTOCHIPS SOFTWARE
 * RELEASED HEREUNDER WILL BE, AT AUTOCHIPS'S OPTION, TO REVISE OR REPLACE THE
 * AUTOCHIPS SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
 * CHARGE PAID BY RECEIVER TO AUTOCHIPS FOR SUCH AUTOCHIPS SOFTWARE AT ISSUE.
 */

/*!
 * @file ac780x_spm.h
 *
 * @brief This file provides system power manage module integration functions interfaces.
 *
 */

#ifndef _AC780X_SPM_H
#define _AC780X_SPM_H

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/* ===========================================  Includes  =========================================== */
#include "ac7803x.h"

/* ============================================  Define  ============================================ */
#define SPM_TIMEOUT_VALUE    (10000UL)    /* for xosc and pll timeout wait */

/* ===========================================  Typedef  ============================================ */
/*!
 * @brief Config the power mode enumeration.
 */
typedef enum
{
    LOW_POWER_MODE_STOP      = 0U,
    LOW_POWER_MODE_STANDBY
} SPM_PowerModeType;

#define IS_POWER_MODE_PARA(MODE) (((MODE) == LOW_POWER_MODE_STOP) || \
                                  ((MODE) == LOW_POWER_MODE_STANDBY))

/*!
 * @brief Periph sleep ack index in SPM enumeration.
 */
typedef enum
{
    SLEEP_ACK_ACMP0 = 0U,
    SLEEP_ACK_RESERVE1,
    SLEEP_ACK_I2C0,
    SLEEP_ACK_I2C1,
    SLEEP_ACK_SPI0,
    SLEEP_ACK_SPI1,
    SLEEP_ACK_RESERVE6,
    SLEEP_ACK_CAN0,
    SLEEP_ACK_CAN1,
    SLEEP_ACK_UART0,
    SLEEP_ACK_UART1,
    SLEEP_ACK_UART2,
    SLEEP_ACK_RESERVE12,
    SLEEP_ACK_RESERVE13,
    SLEEP_ACK_RESERVE14,
    SLEEP_ACK_DMA0,
    SLEEP_ACK_ADC0,
    SLEEP_ACK_EIO,
    SLEEP_ACK_EFLASH,
    SLEEP_ACK_NUM
} SPM_SleepACKType;

#define IS_SLEEP_ACK_PARA(MODULE) (((MODULE) == SLEEP_ACK_ACMP0)  || \
                                   ((MODULE) == SLEEP_ACK_I2C0)   || \
                                   ((MODULE) == SLEEP_ACK_I2C1)   || \
                                   ((MODULE) == SLEEP_ACK_SPI0)   || \
                                   ((MODULE) == SLEEP_ACK_SPI1)   || \
                                   ((MODULE) == SLEEP_ACK_CAN0)   || \
                                   ((MODULE) == SLEEP_ACK_CAN1)   || \
                                   ((MODULE) == SLEEP_ACK_UART0)  || \
                                   ((MODULE) == SLEEP_ACK_UART1)  || \
                                   ((MODULE) == SLEEP_ACK_UART2)  || \
                                   ((MODULE) == SLEEP_ACK_DMA0)   || \
                                   ((MODULE) == SLEEP_ACK_ADC0)   || \
                                   ((MODULE) == SLEEP_ACK_EIO)    || \
                                   ((MODULE) == SLEEP_ACK_EFLASH) )

/*!
 * @brief The module's index in SPM enumeration.
 */
typedef enum
{
    SPM_MODULE_ACMP0 = 0U,
    SPM_MODULE_RESERVE1,
    SPM_MODULE_I2C0,
    SPM_MODULE_I2C1,
    SPM_MODULE_SPI0,
    SPM_MODULE_SPI1,
    SPM_MODULE_RESERVE6,
    SPM_MODULE_CAN0,
    SPM_MODULE_CAN1,
    SPM_MODULE_UART0,
    SPM_MODULE_UART1,
    SPM_MODULE_UART2,
    SPM_MODULE_RESERVE12,
    SPM_MODULE_RESERVE13,
    SPM_MODULE_RESERVE14,
    SPM_MODULE_RTC,
    SPM_MODULE_ADC0,
    SPM_MODULE_GPIO,
    SPM_MODULE_NMI,
    SPM_MODULE_LVD,
    SPM_MODULE_SPM_OVER_COUNT,
    SPM_MODULE_NUM
} SPM_ModuleType;

#define IS_SPM_MODULE_PARA(MODULE) (((MODULE) == SPM_MODULE_ACMP0) || \
                                    ((MODULE) == SPM_MODULE_I2C0)  || \
                                    ((MODULE) == SPM_MODULE_I2C1)  || \
                                    ((MODULE) == SPM_MODULE_SPI0)  || \
                                    ((MODULE) == SPM_MODULE_SPI1)  || \
                                    ((MODULE) == SPM_MODULE_CAN0)  || \
                                    ((MODULE) == SPM_MODULE_CAN1)  || \
                                    ((MODULE) == SPM_MODULE_UART0) || \
                                    ((MODULE) == SPM_MODULE_UART1) || \
                                    ((MODULE) == SPM_MODULE_UART2) || \
                                    ((MODULE) == SPM_MODULE_RTC)   || \
                                    ((MODULE) == SPM_MODULE_ADC0)  || \
                                    ((MODULE) == SPM_MODULE_GPIO)  || \
                                    ((MODULE) == SPM_MODULE_NMI)   || \
                                    ((MODULE) == SPM_MODULE_LVD))

/* ==========================================  Variables  =========================================== */

/* ====================================  Functions declaration  ===================================== */
/*
1) The clocks of all modules are already after wake up and can operate normally.
2) When the wake-up source of UART, CAN, I2C, SPI, LIN generate wake-up signal, enter the IRQ of SPM firstly,then return to the next command of _WFI
3) When the wakeup source of GPIO,RTC,ADC,LVD,ACMP,T-Sensor generates wakeup signals, enter the IRQ of the module, and then return to the next command of _WFI. Each module can ignore the interrupt of SPM
*/
/*!
 * @brief Set the low power mode.
 *
 * @param[in] mode: low power mode, value can be
 *                 - LOW_POWER_MODE_STOP
 *                 - LOW_POWER_MODE_STANDBY
 * @return none
 */
void SPM_SetLowPowerMode(SPM_PowerModeType mode);

/*!
 * @brief Enable fast wakeup mode.
 *
 * @param[in] enable: enable state
 *                   - ENABLE
 *                   - DISABLE
 * @return none
 */
void SPM_EnableFastBoot(ACTION_Type enable);

/*!
 * @brief Enable low voltage detect.
 *
 * @param[in] enable: enable state
 *                   - ENABLE
 *                   - DISABLE
 * @return none
 */
void SPM_EnableLVD(ACTION_Type enable);

/*!
 * @brief Set LVD voltage threshold.
 *
 * @param[in] threahold: 1: high threshold, 0: low threshold
 * @return none
 */
void SPM_SetLVDThreshold(uint8_t threahold);

/*!
 * @brief Set LVD Handler callback function.
 *
 * @param[in] eventFunc: the pointer of the call back function, which will be called in LVD_IRQHandler
 * @return none
 */
void LVD_SetCallback(const DeviceCallback_Type eventFunc);

/*!
 * @brief Enable low voltage reset.
 *
 * @param[in] enable: enable state
 *                   - ENABLE
 *                   - DISABLE
 * @return none
 */
void SPM_EnableLVR(ACTION_Type enable);

/*!
 * @brief Enable internal LDO low voltage reset.
 *
 * @param[in] enable: enable state
 *                   - ENABLE
 *                   - DISABLE
 * @return none
 */
void SPM_EnableDPWRLVR(ACTION_Type enable);

/*!
 * @brief Set LVR voltage threshold.
 *
 * @param[in] threahold: 1: high threshold, 0: low threshold
 * @return none
 */
void SPM_SetLVRThreshold(uint8_t threahold);

/*!
 * @brief Enable XOSC bypass mode.
 *
 * @param[in] enable: enable state
 *                   - ENABLE
 *                   - DISABLE
 * @return none
 */
void SPM_EnableXOSCBypassMode(ACTION_Type enable);

/*!
 * @brief Enable XOSC and wait the XOSC status is ready.
 *
 * @param[in] enable: enable state
 *                   - ENABLE
 *                   - DISABLE
 * @return SUCCESS: xosc set success
 *           ERROR: xosc set fail
 */
ERROR_Type SPM_EnableXOSC(ACTION_Type enable);

/*!
 * @brief Enable PLL and wait for the status is ready.
 *
 * @param[in] enable: enable state
 *                   - ENABLE
 *                   - DISABLE
 * @return SUCCESS: pll set success
 *           ERROR: pll set fail
 */
ERROR_Type SPM_EnablePLL(ACTION_Type enable);

/*!
 * @brief Enable SXOSC and wait the SXOSC status is ready.
 *
 * @param[in] enable: enable state
 *                   - ENABLE
 *                   - DISABLE
 * @return SUCCESS: sxosc set success
 *           ERROR: sxosc set fail
 */
ERROR_Type SPM_EnableSXOSC(ACTION_Type enable);

/*!
 * @brief Enable CAN lowpass filter.
 *
 * @param[in] canIndex: CAN0/1
 * @param[in] enable: enable state
 *                   - ENABLE
 *                   - DISABLE
 * @return none
 */
void SPM_EnableCANLowpassFilter(uint8_t canIndex, ACTION_Type enable);

/*!
 * @brief Config module wakeup function.
 *
 * @param[in] module: module enable in SPM, value can be
 *                   - SPM_MODULE_ACMP0
 *                   - SPM_MODULE_I2C0
 *                   - SPM_MODULE_I2C1
 *                   - SPM_MODULE_SPI0
 *                   - SPM_MODULE_SPI1
 *                   - SPM_MODULE_CAN0
 *                   - SPM_MODULE_CAN1
 *                   - SPM_MODULE_UART0
 *                   - SPM_MODULE_UART1
 *                   - SPM_MODULE_UART2
 *                   - SPM_MODULE_RTC
 *                   - SPM_MODULE_ADC0
 *                   - SPM_MODULE_GPIO
 *                   - SPM_MODULE_NMI
 *                   - SPM_MODULE_LVD
 * @param[in] enable: enable state
 *                   - ENABLE
 *                   - DISABLE
 * @return none
 */
void SPM_EnableModuleWakeup(SPM_ModuleType module, ACTION_Type enable);

/*!
 * @brief Enable which module the SPM wait the ack when do stop.
 *
 * @param[in] module: module enable in SPM, value can be
 *                   - SLEEP_ACK_ACMP0
 *                   - SLEEP_ACK_I2C0
 *                   - SLEEP_ACK_I2C1
 *                   - SLEEP_ACK_SPI0
 *                   - SLEEP_ACK_SPI1
 *                   - SLEEP_ACK_CAN0
 *                   - SLEEP_ACK_CAN1
 *                   - SLEEP_ACK_UART0
 *                   - SLEEP_ACK_UART1
 *                   - SLEEP_ACK_UART2
 *                   - SLEEP_ACK_DMA0
 *                   - SLEEP_ACK_ADC0
 *                   - SLEEP_ACK_EFLASH
 * @param[in] enable: enable state
 *                   - ENABLE
 *                   - DISABLE
 * @return none
 */
void SPM_EnableModuleSleepACK(SPM_SleepACKType module, ACTION_Type enable);

/*!
 * @brief Get sleep ack status.
 *
 * @param[in] none
 * @return sleep ack status value
 */
uint32_t SPM_GetModuleSleepACKStatus(void);

/*!
 * @brief Get the wakeup source flag.
 *
 * @param[in] none
 * @return the wakeup source flag
 */
uint32_t SPM_GetModuleWakeupSourceFlag(void);

/*!
 * @brief Clear the wakeup source flag.
 *
 * @param[in] none
 * @return none
 */
void SPM_ClearWakeupSourceFlag(void);

/*!
 * @brief Set SPM IRQHandler callback function.
 *
 * @param[in] eventFunc: the pointer of the call back function, which will be called in SPM_IRQHandler
 * @return none
 */
void SPM_SetCallback(const DeviceCallback_Type eventFunc);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* _AC780X_SPM_H */

/* =============================================  EOF  ============================================== */
